package net.thxjj.adminServer.mongodao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import net.thxjj.adminServer.entity.aep.DevLog;
import net.thxjj.adminServer.entity.aep.HeartData;
import net.thxjj.adminServer.entity.aep.SmokeData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Component
public class MongoEventDao {
    @Autowired
    private MongoTemplate mongoTemplate;

    //导入所有数据
    public void saveAllData(List<DevLog> list){
        mongoTemplate.insert(list,DevLog.class);
    }

    private void updateDevLog(DevLog devLog) {
        Query query = new Query(Criteria.where("deviceId").is(devLog.getDeviceId()).and("createTime").is(devLog.getCreateTime()));
        Update update = new Update()
                .set("eventType",devLog.getEventType())
                .set("eventContent",devLog.getEventContent())
                .set("imei",devLog.getImei());

        mongoTemplate.upsert(query,update, DevLog.class);
    }

    private DevLog findDevLogByDeviceIdAndTime(String deviceId, long time){
        Query query = new Query(Criteria.where("deviceId").is(deviceId).and("createTime").is(time));
        return mongoTemplate.findOne(query,DevLog.class);
    }

    //导入校验（如果有timestamp和deviceId重合则更新）
    public void saveDevLogs(List<DevLog> list){
        for (DevLog devLog:
                list) {
            DevLog po = findDevLogByDeviceIdAndTime(devLog.getDeviceId(),devLog.getCreateTime());
            if(po==null){
                mongoTemplate.save(devLog);
            }else{
                updateDevLog(devLog);
            }
        }
    }

    public void saveDevLog(DevLog devLog){
        DevLog po = findDevLogByDeviceIdAndTime(devLog.getDeviceId(),devLog.getCreateTime());
        if(po==null){
            mongoTemplate.save(devLog);
        }else{
            updateDevLog(devLog);
        }
    }


    public DevLog getNewstEvent(String device_id,String content){
        String pattern = ".*?"+content+".*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        return mongoTemplate.findOne(query, DevLog.class);
    }

    public DevLog getNewstEventByTime(String device_id,long time,String content){
        String pattern = ".*?"+content+".*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern),Criteria.where("createTime").lt(time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        return mongoTemplate.findOne(query, DevLog.class);
    }

    public List<DevLog> getEventAtTime(String device_id,long start_time,long end_time,String content){
        String pattern = ".*?"+content+".*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }

    public List<DevLog> getFaultDataAtTime(String device_id,long start_time,long end_time){
        String pattern1 = ".*?\"error\":1.*";
        String pattern2 = ".*?\"error\":2.*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern1),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Criteria criteria2 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern2),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(new Criteria().orOperator(criteria1,criteria2));
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }

    public List<DevLog> getLowVoltDataAtTime(String device_id,long start_time,long end_time){
        String pattern1 = ".*?\"error\":3.*";
        String pattern2 = ".*?\"error\":4.*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern1),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Criteria criteria2 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern2),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(new Criteria().orOperator(criteria1,criteria2));
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }

    public List<DevLog> getDismantleDataAtTime(String device_id,long start_time,long end_time){
        String pattern1 = ".*?tamper_alarm.*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern1),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }

    public List<DevLog> getDataAtTime(String device_id,long start_time,long end_time){
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.DESC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }

    public DevLog getEarliestEventAtTime(String device_id,long start_time,long end_time,String content){
        String pattern = ".*?"+content+".*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("eventContent").regex(pattern),Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.findOne(query, DevLog.class);
    }

    //获取最早的报警事件数据(根据event_content搜索)
    public DevLog getEarliestEvent(String device_id){
        Criteria criteria1 = Criteria.where("deviceId").is(device_id);
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.findOne(query, DevLog.class);
    }

    //event_log_ 模糊查询
    private List<DevLog> getDevLogsByLikes(String device_id,long start_time,long end_time,String content){
        String pattern = ".*?"+content+".*";
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("createTime").gt(start_time),Criteria.where("createTime").lt(end_time),Criteria.where("eventContent").regex(pattern));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"createTime"));
        return mongoTemplate.find(query, DevLog.class);
    }


    public List<SmokeData> getSmokeValueList(String device_id, long start_time,long end_time){

        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"smoke_value");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
             devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("smoke_value");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setSmoke_value(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query = new Query(criteria1);
        query.with(new Sort(Sort.Direction.ASC,"timestamp"));

        List<SmokeData> smokeDataList2 = mongoTemplate.find(query,SmokeData.class);
        smokeDataList.addAll(smokeDataList2);
        Collections.sort(smokeDataList);

        return smokeDataList;
    }


    public List<SmokeData> getBatteryValueList(String device_id,long start_time,long end_time){

        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"battery_value");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
                devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("battery_value");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setBattery_value(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<HeartData> heartDataList = mongoTemplate.find(query1,HeartData.class);
        for (HeartData heartData:
                heartDataList) {

            SmokeData data = new SmokeData().setDeviceId(heartData.getDeviceId()).setBattery_value(heartData.getBattery_value()).setTimestamp(heartData.getTimestamp());
            smokeDataList.add(data);
        }
        Criteria criteria2 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query2 = new Query(criteria2);
        query2.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList2 = mongoTemplate.find(query2,SmokeData.class);

        smokeDataList.addAll(smokeDataList2);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

    public List<SmokeData> getSmokeHappenList(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"\"smoke_state\":0");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devLog:
                devLogs) {

            SmokeData data = new SmokeData().setDeviceId(devLog.getDeviceId()).setTimestamp(devLog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("smoke_state").is(0),Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        smokeDataList.addAll(smokeDataList1);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

    public long getSmokeRecoryPoint(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"\"smoke_state\":1");
        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("smoke_state").is(1),Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        long time1 = 0;
        long time2 = 0;
        if(devLogs.size()>0&&smokeDataList1.size()>0){
            time1 = devLogs.get(0).getCreateTime();
            time2 = smokeDataList1.get(0).getTimestamp();
            return Math.min(time1, time2);
        }else if(devLogs.size()>0){
            time1 = devLogs.get(0).getCreateTime();
            return time1;
        }else if(smokeDataList1.size()>0){
            time2 = smokeDataList1.get(0).getTimestamp();
            return time2;
        }else {
            return 0;
        }



    }

    public List<SmokeData> getSmokeStateHistory(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"smoke_state");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
                devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("smoke_state");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setSmoke_state(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        smokeDataList.addAll(smokeDataList1);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

    public List<SmokeData> getSnrHistory(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"snr");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
                devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("snr");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setSnr(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        smokeDataList.addAll(smokeDataList1);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

    public List<SmokeData> getSignalPowerHistory(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"signalPower");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
                devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("signalPower");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setSignalPower(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        smokeDataList.addAll(smokeDataList1);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

    public List<SmokeData> getTxPowerHistory(String device_id,long start_time,long end_time){
        List<DevLog> devLogs = getDevLogsByLikes(device_id,start_time,end_time,"tx_Power");
        List<SmokeData> smokeDataList = new ArrayList<>();
        for (DevLog devlog:
                devLogs) {
            long value = 0;
            try {
                JSONObject jsonObject = JSON.parseObject(devlog.getEventContent());
                value = jsonObject.getLongValue("tx_Power");
            }catch (JSONException e){
                e.printStackTrace();
            }

            SmokeData data = new SmokeData().setDeviceId(devlog.getDeviceId()).setTx_Power(value).setTimestamp(devlog.getCreateTime());
            smokeDataList.add(data);
        }

        Criteria criteria1 = Criteria.where("deviceId").is(device_id).andOperator(Criteria.where("timestamp").gt(start_time),Criteria.where("timestamp").lt(end_time));
        Query query1 = new Query(criteria1);
        query1.with(new Sort(Sort.Direction.ASC,"timestamp"));
        List<SmokeData> smokeDataList1 = mongoTemplate.find(query1,SmokeData.class);
        smokeDataList.addAll(smokeDataList1);

        Collections.sort(smokeDataList);

        return smokeDataList;
    }

}
